package com.dq.controller.api.subscribe;

import com.dq.controller.in.*;
import com.dq.controller.in.request.SignatureRequest;
import com.dq.domain.sys.user.user.BossUser;
import com.dq.domain.sys.user.user.StaffUser;
import com.dq.exception.customException.AdminException;
import com.dq.controller.in.request.SubscribeAdd;
import com.dq.vo.ListDataVo;
import com.dq.vo.ListVo;
import com.dq.vo.Vo;
import com.dq.domain.subscribe.Subscribe;
import com.dq.vo.baseVo.VO;

import com.dq.domain.message.oneself.SubscribeMessage;
import com.dq.domain.org.Org;
import com.dq.domain.sys.user.user.base.SysUser;
import com.dq.domain.sys.user.user.WxUser;
import com.dq.service.AllService;
import com.dq.utils.PageableUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.google.zxing.EncodeHintType;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;



/**
 * @Author luchangtong
 * @Date 2019/11/22 16:14
 */
@Api(description = "预约")
@RestController
@RequestMapping("api/subscribe")
public class SubscribeController extends AllService {
    @ApiOperation("预约服务")
    @PostMapping("subscribeService")
    public VO subscribeService(@RequestBody SubscribeAdd subscribeAdd) throws AdminException {
        subscribeService.subscribe(subscribeAdd);
        return new Vo(HttpStatus.OK);
    }

    @ApiOperation("取消预约")
    @PostMapping("cancelSubscribe/{subscribeId}")
    @Transactional
    public Vo cancelSubscribe(@PathVariable @ApiParam("预约单id")Long subscribeId) throws AdminException{

        return subscribeService.changeSubscribeStatus(subscribeId,Subscribe.SubscribeStatus.cancel,"取消");
    }

    @ApiOperation("预约确认")
    @PostMapping("confirm/{subscribeId}")
    public Vo confirm(@PathVariable @ApiParam("预约单id")Long subscribeId) throws AdminException{
        Org org = (Org) shiroService.getDept();
        Subscribe subscribe = dao.get(Subscribe.class,subscribeId);
        if(subscribe == null){
            throw new AdminException("此预约不存在");
        }
        subscribe.setSubscribeStatus(Subscribe.SubscribeStatus.confirmed);
        Subscribe save = subscribeRepository.save(subscribe);
        subscribeService.subscribeMessage(subscribe,subscribe.getWxUser(), SubscribeMessage.UserType.client, "预约确认");

        //
        subscribeMessageService.subscribeRedisBegin(save);

        return new Vo(HttpStatus.OK);
    }

    @ApiOperation("拒绝预约")
    @PostMapping("refuse")
    public Vo refuse(@RequestBody @Valid SubscribeQuery subscribeQuery) throws AdminException{
        Subscribe subscribe = dao.get(Subscribe.class, subscribeQuery.getSubscribeId());
        if(subscribe == null){
            throw new AdminException("此预约不存在");
        }
        if(Subscribe.SubscribeStatus.refuse.equals(subscribe.getSubscribeStatus())){
            throw new AdminException("预约单已经拒绝过");
        }
        subscribe.setSubscribeStatus(Subscribe.SubscribeStatus.refuse);
        subscribe.setFeedBack(subscribeQuery.getRefuse());

        SysUser user = sysUserService.getUser();
        subscribe.setUpdateUser(user);
        subscribeRepository.save(subscribe);
        subscribeService.subscribeMessage(subscribe, subscribe.getWxUser(), SubscribeMessage.UserType.client, "预约拒绝");
        return new Vo(HttpStatus.OK);
    }

    @ApiOperation(value = "技师看预约记录",notes = "")
    @PostMapping("findByStaffList")
    public Vo findByStaffList(@RequestBody StaffSubscribeQuery staffSubscribeQuery) throws AdminException{

        return subscribeService.list(staffSubscribeQuery);
    }

    /*@ApiOperation("技师看预约记录")
    @GetMapping("findByStaffSubscribeList/{page}/{size}")
    public ListVo findByStaffSubscribeList(@PathVariable @ApiParam("页数") Integer page,
                                           @PathVariable @ApiParam("页长") Integer size) throws AdminException{
        SysUser user = shiroService.getUser();
        List<Subscribe> subscribes = subscribeRepository.findByTechnicianUserAndSubscribeStatusAndDeletedFalse(user, Subscribe.SubscribeStatus.serviced, PageableUtil.get(page,size)).getContent();
        Long totalNum = subscribeRepository.countByTechnicianUserAndSubscribeStatusAndDeletedFalse(user, Subscribe.SubscribeStatus.serviced);
        List<Subscribe.StaffUserSubscribe> list = new ArrayList<>();
        subscribes.forEach(subscribe -> {
            list.add(subscribe.toStaffUserSubscribe());
        });
        return new ListVo(list,totalNum);
    }*/

    @PostMapping("/findAllProjectByPage")
    @ApiOperation("查看门店所有可以做的项目")
    public Vo findAllProjectByPage(@RequestBody OrgServiceProjectQuery orgServiceProjectQuery)throws AdminException{
        return orgServiceProjectService.list(orgServiceProjectQuery);
    }

    @PostMapping("/findStaffByProject")
    @ApiOperation("根据服务项目id查询推荐老师，根据老师id查看可做项目")
    public Vo findStaffByProject(@RequestBody StaffUserServiceProjectCentreQuery staffUserServiceProjectCentreQuery)throws AdminException{
        return staffUserServiceProjectCentreService.list(staffUserServiceProjectCentreQuery);
    }

    @PostMapping("/findStaffByOrg")
    @ApiOperation("根据门店展示技师")
    public Vo findStaffByOrg(@RequestBody CustomerQuery customerQuery) throws AdminException{
        List<BossUser> staffUserList = staffUserService.findByWhere(customerQuery);
        Long totalCount = staffUserService.countByWhere(customerQuery);
        List<BossUser.LoginVo> toList = new ArrayList<>();
        staffUserList.forEach(bossUser -> {
            BossUser.LoginVo loginVo = bossUser.toLoginVo();
            loginVo.setLableStrList(wxUserService.getWxUserLable(bossUser));
            toList.add(loginVo);
        });
        return new ListDataVo(toList,totalCount);
    }

    @PostMapping("/findTimeByOrgAndProject")
    @ApiOperation("根据服务项目所选技师查看预约时间")
    public Vo findTimeByOrgAndProject(@RequestBody TimeQuery timeQuery)throws AdminException{

        return subscribeService.findTimeByOrgAndProject(timeQuery);
    }

    @PostMapping("/signature")
    @ApiOperation("结账签字确认")
    @Transactional(rollbackFor = Exception.class)
    public Vo signature(@RequestBody SignatureRequest signatureRequest) throws AdminException{
        Subscribe subscribe = dao.get(Subscribe.class,signatureRequest.getSubscribeId());
        if(subscribe == null){
            throw new AdminException("预约单异常");
        }
        subscribe.setSubscribeStatus(Subscribe.SubscribeStatus.signature);
        subscribe.setSignatureImg(signatureRequest.getImgUrl());
        subscribeRepository.save(subscribe);
        List<Long> longs = new ArrayList<>();
        List<String> strings = new ArrayList<>();
        BossUser staffUser = subscribe.getTechnicianUser();
        String staffName = "";
        Long staffId = null;
        if(staffUser.getId() != null){
            staffId = staffUser.getId();
            longs.add(staffId);
        }
        if(!"".equals(staffUser.getUserRealcName()) && staffUser.getUserRealcName() != null){
            staffName = staffUser.getUserRealcName();
            strings.add(staffName);
        }
        WxUser wxUser = (WxUser) subscribe.getWxUser();
        wxUser.setServeTime(System.currentTimeMillis());
        wxUser.setPayTime(System.currentTimeMillis());
        wxUser.setServeUserIdList(Joiner.on(",").join(longs));
        wxUser.setServeUserNameList(Joiner.on(",").join(strings));
        BigDecimal payTotal = BigDecimal.ZERO;
        if(wxUser.getPayTotal() != null){
            payTotal = wxUser.getPayTotal();
        }
        wxUser.setPayTotal(payTotal.add(subscribe.getOriginalPrice()));
        wxUserRepository.save(wxUser);
        return new Vo(HttpStatus.OK);
    }

    @ApiOperation("店长核销")
    @PostMapping("confirmService/{id}")
    public Vo confirmService(@PathVariable Long id)throws AdminException{

        return subscribeService.changeSubscribeStatus(id, Subscribe.SubscribeStatus.cancelled,"到店核销");
    }
    @ApiOperation("技师结束服务")
    @PostMapping("endService/{id}")
    public Vo endService(@PathVariable Long id) throws AdminException{

        return subscribeService.changeSubscribeStatus(id, Subscribe.SubscribeStatus.stayPaid,"");
    }
    /**
     * 现金结账/在线支付，会员卡积分结账/会员卡项目次数结账
     * @return
     * @throws AdminException
     */
    @ApiOperation("结账")
    @PostMapping("paySubscribe")
    public Vo paySubscribe(@RequestBody SubscribePayRequest request) throws AdminException{
        return subscribeService.paySubscribe(request);
    }



}
